Closes #759.
pub struct Profile {
env: String, // compile, test, dev, bench, etc.
opt_level: uint,
+ lto: bool,
codegen_units: Option<uint>, // None = use rustc default
debug: bool,
rpath: bool,
Profile {
env: String::new(),
opt_level: 0,
+ lto: false,
codegen_units: None,
debug: false,
rpath: false,
Profile {
env: "compile".to_string(), // run in the default environment only
opt_level: 0,
+ lto: false,
debug: true,
.. Profile::default()
}
Profile {
env: "bench".to_string(),
opt_level: 3,
+ lto: false,
test: true,
dest: Some("release".to_string()),
.. Profile::default()
Profile {
env: "release".to_string(),
opt_level: 3,
+ lto: false,
dest: Some("release".to_string()),
.. Profile::default()
}
self.opt_level
}
+ pub fn get_lto(&self) -> bool {
+ self.lto
+ }
+
pub fn get_codegen_units(&self) -> Option<uint> {
self.codegen_units
}
self
}
+ pub fn lto(mut self, lto: bool) -> Profile {
+ self.lto = lto;
+ self
+ }
+
pub fn codegen_units(mut self, units: Option<uint>) -> Profile {
self.codegen_units = units;
self
// to the actual hash of a profile.
let Profile {
opt_level,
+ lto,
codegen_units,
debug,
rpath,
custom_build: _,
} = *self;
- (opt_level, codegen_units, debug, rpath, for_host, dest, harness).hash(into)
+ (opt_level, lto, codegen_units, debug,
+ rpath, for_host, dest, harness).hash(into)
}
}
.env("TARGET", Some(cx.target_triple()))
.env("DEBUG", Some(profile.get_debug().to_string()))
.env("OPT_LEVEL", Some(profile.get_opt_level().to_string()))
+ .env("LTO", Some(profile.get_lto().to_string()))
.env("PROFILE", Some(profile.get_env()));
for arg in cmd {
p = p.arg(arg);
if profile.get_opt_level() != 0 {
cmd = cmd.arg("--opt-level").arg(profile.get_opt_level().to_string());
}
-
- match profile.get_codegen_units() {
- Some(n) => cmd = cmd.arg("-C").arg(format!("codegen-units={}", n)),
- None => {},
+ if target.is_bin() && profile.get_lto() {
+ cmd = cmd.args(["-C", "lto"]);
+ } else {
+ // @alexchrichton says that there may be some restrictions with LTO
+ // and codegen-units, so that we should only add codegen units when
+ // LTO is not used.
+ match profile.get_codegen_units() {
+ Some(n) => cmd = cmd.arg("-C").arg(format!("codegen-units={}", n)),
+ None => {},
+ }
}
if profile.get_debug() {
#[deriving(Decodable, Clone, Default)]
pub struct TomlProfile {
opt_level: Option<uint>,
+ lto: Option<bool>,
codegen_units: Option<uint>,
debug: Option<bool>,
rpath: Option<bool>,
None => return profile,
};
let opt_level = toml.opt_level.unwrap_or(profile.get_opt_level());
+ let lto = toml.lto.unwrap_or(profile.get_lto());
let codegen_units = toml.codegen_units;
let debug = toml.debug.unwrap_or(profile.get_debug());
let rpath = toml.rpath.unwrap_or(profile.get_rpath());
- profile.opt_level(opt_level).codegen_units(codegen_units).debug(debug)
- .rpath(rpath)
+ profile.opt_level(opt_level).lto(lto).codegen_units(codegen_units)
+ .debug(debug).rpath(rpath)
}
fn target_profiles(target: &TomlTarget, profiles: &TomlProfiles,
must be present\n"));
})
+test!(lto_build {
+ let mut p = project("foo");
+ p = p
+ .file("Cargo.toml", r#"
+ [package]
+
+ name = "test"
+ version = "0.0.0"
+ authors = []
+ lto = true
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0).with_stdout(format!("\
+{compiling} test v0.0.0 ({url})
+{running} `rustc {dir}{sep}src{sep}lib.rs --crate-name test --crate-type bin -g \
+ -C lto \
+ -C metadata=[..] \
+ -C extra-filename=-[..] \
+ --out-dir {dir}{sep}target \
+ --dep-info [..] \
+ -L {dir}{sep}target \
+ -L {dir}{sep}target{sep}deps`
+",
+running = RUNNING, compiling = COMPILING, sep = path::SEP,
+dir = p.root().display(),
+url = p.url(),
+)));
+})
+
test!(verbose_build {
let mut p = project("foo");
p = p